package com.ymt.fmd.platform.service;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

import com.ymt.fmd.platform.dao.mysql.PServiceMapper;
import com.ymt.fmd.platform.model.PService;
import com.ymt.fmd.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


@Service
public class PServiceService {

	/**
	 * Logger
	 */
	private Logger logger = Logger.getLogger(PServiceService.class.getName());

	@Autowired
	private Environment env;
	
	/**
	 * PServiceMapper
	 */
	@Autowired
	private PServiceMapper psDao;
	
	/**
	 * get service
	 * @param id
	 * @param lang
	 * @param timezoneOffset
	 * @return
	 */
	public String get(String id, String lang, int timezoneOffset) {
		logger.finer("get id="+id);
		PService bo = psDao.selectByPrimaryKey(id);
		logger.finer("get bo="+bo);
		JSONObject cfg = JSONObject.parseObject(bo.getSvcConfig());//turn string to object
		JSONObject bojo = DhxUtil.toJsonWithDate(bo, lang, timezoneOffset);
		bojo.put("svcConfig", cfg);
		return bojo.toString();
	}
	
	/**
	 * save service
	 * @param boStr
	 * @param loginName
	 * @param displayName
	 * @param lang
	 * @return
	 */
	public String save(String tenantId, String boStr, String loginName, 
			String displayName, String lang) {
		logger.finer("saving bostr="+boStr);
		JSONObject boJo = JSONObject.parseObject(boStr);
		String id = boJo.getString("id");
		if (id==null || id.length()==0) {
			PService bo = new PService();
			id = "SVC-"+UUID.randomUUID().toString();
			bo.setId(id);
			if (tenantId!=null) {
				bo.setTenantId(Integer.parseInt(tenantId));
			}
			bo.setSvcDesc(boJo.getString("svcDesc"));
			String status = boJo.getString("status");
			bo.setStatus(status==null || status.length()==0 ? "00" : status);
			String category = boJo.getString("category");
			bo.setCategory(category==null || category.length()==0 ? "REST" : category);
			bo.setCreator(loginName);
			bo.setCreatorName(displayName);
			bo.setCreateTime(DateUtil.getGMTDate());
			bo.setUpdator(loginName);
			bo.setUpdatorName(displayName);
			bo.setUpdateTime(DateUtil.getGMTDate());
			bo.setSvcConfig(boJo.getJSONObject("svcConfig").toString());
			psDao.insert(bo);
		} else {
			PService bo = psDao.selectByPrimaryKey(id);
			bo.setSvcDesc(boJo.getString("svcDesc"));
			bo.setStatus(boJo.getString("status"));
			bo.setCategory(boJo.getString("category"));
			bo.setUpdator(loginName);
			bo.setUpdatorName(displayName);
			bo.setUpdateTime(DateUtil.getGMTDate());
			JSONObject cfg = boJo.getJSONObject("svcConfig");
			bo.setSvcConfig(cfg!=null ? cfg.toString() : null);
			psDao.updateByPrimaryKeySelective(bo);
			id = bo.getId();
		}
		return id;
	}
	
	/**
	 * delete service
	 * @param id
	 * @return
	 */
	public int delete(String id) {
		logger.finer("delete id="+id);
		return psDao.deleteByPrimaryKey(id);
	}
	
	/**
	 * query service
	 * @param queryParams
	 * @param fInd
	 * @param lInd
	 * @param timezoneOffset
	 * @param lang
	 * @param ordercolumns
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String query(String tenantId, 
			String queryParams, int fInd, int lInd, int timezoneOffset, 
			String lang, String ordercolumns) {
		logger.finer("query queryParams="+queryParams);
		Map<String, Object> params = new HashMap<String,Object>();
		Map<String, Object> bo = new HashMap<String,Object>();
		if (queryParams!=null) {
			bo.putAll(JSONObject.parseObject(queryParams));
		}
		if (tenantId!=null) {
			bo.put(Const.TENANT_ID, tenantId);
		}
		params.put("bo", bo);
		params.put("fromRow", fInd-1);
		params.put("toRow", lInd);
		params.put("rows", lInd - fInd + 1);
		params.put("timezoneOffset", timezoneOffset);
		params.put("orderby", DhxUtil.parseGridOrderBy(ordercolumns));  //[{"CREATE_TIME":"DESC"}]
		logger.finer("query params="+params);
		List<Map<String,?>> list = psDao.pagingSelect(params);
		int total = Integer.parseInt(psDao.pagingSelectCount(params).get("COUNT").toString());
		String[] cols = new String[]{"ID","SVC_DESC","CATEGORY","STATUS","UPDATE_TIME","UPDATOR_NAME","CREATE_TIME","CREATOR_NAME","UPDATOR","CREATOR"};
		String rtn= DhxUtil.toGridJsonStr(list, 
				cols, fInd, total, timezoneOffset, lang);
		logger.finer("query returns:\n"+rtn);
		return rtn;
	}
	
	public Map find(String tenantId, 
			int start, int limit, int timezoneOffset, 
			String lang, String query, String ordercolumns) {

		Map<String, Object> params = new HashMap<String,Object>();
		Map<String, Object> bo = new HashMap<String,Object>();
		if (query!=null) {
			bo.put("query", query);
		}
		if (tenantId!=null) {
			bo.put(Const.TENANT_ID, tenantId);
		}
		params.put("bo", bo);
		params.put("fromRow", start);
//		params.put("toRow", lInd);
		params.put("rows", limit);
		params.put("timezoneOffset", timezoneOffset);
		params.put("orderby", ordercolumns);  //[{"CREATE_TIME":"DESC"}]
		int total = Integer.parseInt(psDao.pagingSelectCount(params).get("COUNT").toString());
		List<Map<String,?>> lists = psDao.pagingSelect(params);
		
		for (int i = 0; i < lists.size(); i++) {			// 循环遍历集合，取出其中时间信息格式化
			Date createTime = (Date) lists.get(i).get("CREATE_TIME");
			Date updateTime = (Date) lists.get(i).get("UPDATE_TIME");
			Map<String,Object> fMap = (Map<String,Object>)lists.get(i);
			
			if (createTime != null){
				Date createDate = DateUtil.getLocaleDate(createTime, timezoneOffset);		// 格式化时间
				fMap.put("CREATE_TIME", createDate);
			}

			if (updateTime != null) {
				Date updateDate = DateUtil.getLocaleDate(updateTime, timezoneOffset);
				fMap.put("UPDATE_TIME", updateDate);
			}
		}
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("total", total);
		result.put("lists", lists);
		return result;

	}
	
	
	/**
	 * call rest service
	 * @param svcId
	 * @param intfvars
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public String callRestService(String svcId, JSONArray intfvars) throws UnsupportedEncodingException {
		PService svc = psDao.selectByPrimaryKey(svcId);
		if (!"REST".equalsIgnoreCase(svc.getCategory())) {
			return null;
		}
		JSONObject cfg = JSONObject.parseObject(svc.getSvcConfig());
		String method = cfg.getString("method");
		String url = cfg.getString("uri");
		if (!url.toLowerCase().startsWith("http")) {
			url = env.getProperty("bpmp.site-url") + url;
		}
		Map<String, String> params = new HashMap<String, String>();
		if (intfvars!=null && intfvars.size()>0) {
			for (int i=0; i<intfvars.size(); i++) {
				JSONObject var = intfvars.getJSONObject(i);
				String varname = var.getString("varname");
				Object dv = var.get("default");
				if (dv!=null && dv.toString().length()>0) {
					params.put(varname, dv.toString());
				} else {
					params.put(varname, "");
				}
			}
		}
		JerseyRestClient client = new JerseyRestClient();
		String rtn = null;
		if ("GET".equalsIgnoreCase(method)) {
			rtn = client.get(url, params);
		} else if ("POST".equalsIgnoreCase(method)) {
			rtn = client.post(url, params);
		} else if ("PUT".equalsIgnoreCase(method)) {
			rtn = client.put(url, params);
		} else if ("DELETE".equalsIgnoreCase(method)) {
			rtn = client.delete(url, params);
		} else {
			throw new RuntimeException("Unsupported method: "+method);
		}
		return rtn;
	}

	public String queryTable(String tableName, int fromRow, int toRow,int timezoneOffset,
			String lang, String ordercolumns) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("tableName", tableName);
		param.put("fromRow", fromRow);
		param.put("toRow", toRow);
//		param.put("ordercolumns", tableName);
		param.put("tableName", tableName);
		List<Map<String,?>> list = psDao.queryTable(param);
		int total = psDao.queryTableTotal(param);
		String[] cols = new String[]{"TABLE_NAME"};
		String rtn= DhxUtil.toGridJsonStr(list, 
				cols, fromRow, total, timezoneOffset, lang);
		logger.finer("query returns:\n"+rtn);
		return rtn;
	}
	

}
